package com.qy33.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;

/**
 * @author henry_li
 * 
 */
public class DateUtil {
	/**
	 * DateUtils
	 */
	private DateUtil() {
	}

	
	public static final String[] DAYARRAY = new String[]{"", "周一", "周二", "周三", "周四", "周五", "周六", "周日"};

	/**
	 * 获取当前日期, 默认格式为yyyy-MM-dd
	 * 
	 * @return String
	 */
	public static String getDate() {
		return DateUtil.formatDate("yyyy-MM-dd");
	}
	
	public static String getDateTime() {
		return DateUtil.formatDate("yyyy-MM-dd HH:mm:ss");
	}
	
	public static String getTime() {
		return DateUtil.formatDate("HH:mm:ss");
	}

	/**
     * 获取当前日期字符串，格式为yyyyMMdd
     * @return String
     */
    public static String getCurrentDate()
    {
        return new SimpleDateFormat("yyyyMMdd").format(new Date());
    }
    
    /**
     * 获取当前日期字符串，格式为yyyy-MM-dd
     * @return String
     */
    public static String getCurrentToDate()
    {
        return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    }
    /**
	 * 获取当前时间字符串，格式为HHmmss
	 * @return String
	 */
	public static String getCurrentTime()
	{
		return new SimpleDateFormat("HHmmss").format(new Date());
	}

	public static String getCurrentDateTime()
	{
		return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
	}
	/**
	 * 获取当前时间的字符串，格式为yyyy-MM-dd HH:mm:ss
	 * @return String
	 */
	public static String getCurrentPrettyDateTime()
	{
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
	}
	
	/**
	 * 获取对应Date的日期字符串，格式为yyyyMMdd
	 * @param date 源Date
	 * @return
	 */
	public static String getDateYYYYMMDD(Date date)
	{
		return new SimpleDateFormat("yyyyMMdd").format(date);
	}
	/**
	 * getDate
	 * 
	 * @param pattern
	 *            String
	 * @return String
	 */
	public static Date formatDate(String date, String pattern) {
		if (StringUtils.isEmpty(date)) {
			return null;
		}
		
		try {
			DateFormat format = new SimpleDateFormat(pattern);
			Date result = format.parse(date);

			String resultStr = format.format(result);
			if (date.equals(resultStr)) {
				return result;
			}
			
			// 如果结果不一致，则再处理
			if (date.length() < 10) {
				resultStr = resultStr.replaceAll("(?<=\\-{1})0{1}", "");
			}
			if (date.equals(resultStr)) {
				return result;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return null;
	}
	
	/**
	 * getDate
	 * 
	 * @param pattern
	 *            String
	 * @return String
	 */
	public static String formatDate(String pattern) {
		return new SimpleDateFormat(pattern).format(new Date());
	}

	/**
	 * @param date
	 * @return
	 */
	public static String getDate(Date date) {
		return DateUtil.getDate(date, "yyyy-MM-dd");
	}

	/**
	 * @param date
	 * @return
	 */
	public static String getDateTime(Date date) {
		return DateUtil.getDate(date, "yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String getDate(Date date, String pattern) {
		return new SimpleDateFormat(pattern).format(date);
	}

	public final static int getDayOfMonth(Date date) {
		Calendar calendar = GregorianCalendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_MONTH);
	}

	public final static int getDayOfWeek(Date date) {
		Calendar calendar = GregorianCalendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}
	
	/**
	 * getDateDiffDays
	 * 
	 * @param curDate
	 * @param oriDate
	 * @return int
	 * @author henry_li
	 * @since 2006-12-28
	 */
	public static int getDateDiffDays(Date curDate, Date oriDate) {
		return  Math.abs(getDateDiffDay(curDate, oriDate));
	}
	
	/**
	 * 计算时间差,>0表示当前开始日期为明天, <0表示当前开始日期是昨天
	 * @param curDate
	 * @param oriDate
	 * @return
	 */
	public static int getDateDiffDay(Date curDate, Date oriDate)
	{
		final int MS_PER_DAY = 1000 * 60 * 60 * 24;
		Date startDate = new Date();
		Date endDate = new Date();

		try
		{
			startDate = new java.text.SimpleDateFormat("yyyy-MM-dd").parse(getDate(curDate));
			endDate = new java.text.SimpleDateFormat("yyyy-MM-dd").parse(getDate(oriDate));
		}
		catch (ParseException ex)
		{
			ex.printStackTrace();
		}

		return (int)(startDate.getTime() - endDate.getTime()) / MS_PER_DAY;
	}
	
	public static String addDays(String date, int num, String pattern) {
		return DateUtil.getDate(DateUtil.addDays(DateUtil.formatDate(date, pattern), num), pattern);
	}
	
	public static Date addDays(Date date, int num) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		}
		
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(Calendar.DAY_OF_MONTH, num);
		
		return c.getTime();
	}
	
    public static Date addMonths(Date date, int num) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, num);
        return c.getTime();
    }
    
    public static Date addYears(Date date, int num) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, num);
        return c.getTime();
    }
    
 	public static Date getStartDate(String startDate){
		return formatDate(startDate, "yyyyMMdd");
	}
	
	public static Date getEndDate(String endDate){
		Date date = formatDate(endDate, "yyyyMMdd");
		
		return date == null ? null : addDays(date, 1);
	}
	
	public static Date getStartDate(Date startDate) {
		return clearTime(startDate);
	}
	
	public static Date clearTime(Date date) {
		if (date == null) {
			return null;
		}
		
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		
		return c.getTime();
	}
	
	public static int getHour(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR_OF_DAY);
	}
	
	public static int getMinute(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}
	
	public static Date getEndDate(Date endDate){
		Date date = clearTime(endDate);
		
		return date == null ? null : addDays(date, 1);
	}
	
	public static Date toDate(String str){
		return toDate(str,"yyyy-MM-dd");
	}
	
	public static Date toDateTime(String str){
		return toDate(str,"yyyy-MM-dd HH:mm:ss");
	}
	
	//指定日期的开始时间
	public static Date toDateTimeBegin(Date date)
	{
		String strDate = DateUtil.getDate(date) + " 00:00:00";
		return DateUtil.toDateTime(strDate);
	}
	
	//指定日期的结束时间
	public static Date toDateTimeEnd(Date date)
	{
		String strDate = DateUtil.getDate(date) + " 23:59:59";
		return DateUtil.toDateTime(strDate);
	}
	
	public static Date toTimestamp(String str){
		Date date = toDateTime(str);
		return new Timestamp(date.getTime());
	}
	
	/**
	 * 将指定格式的字符串转换成日期类型
	 * 
	 * @param date 待转换的日期字符串
	 * @param dateFormat 日期格式字符串
	 * @return Date
	 */
	public static Date toDate(String dateStr, String dateFormat) {
		if (dateStr == null || dateStr.equals("")) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		try {
			return sdf.parse(dateStr);
		} catch (Exception e) {
			throw new RuntimeException("Parse date failed:" + e.getMessage());
		}
	}
	
	 /**
     * 计算两个时间段之间包括几天
     * @param strStartDate
     * @param strEndDate
     * @return
     */
    public static int getDateOffset(String strStartDate, String strEndDate) {
        return getDateOffset(strToLongDate(strStartDate), strToLongDate(strEndDate));
    }
    
    /**
     * 将字符日期(yyyy-mm-dd)转换成日期
     * @param strDate
     * @return 转换失败返回null
     */
    public static Date strToLongDate(String strDate){
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        format.setLenient(false);
        Date dResult = null;
        try {
            dResult = format.parse(strDate);
        } catch (ParseException e) {            
            e.printStackTrace();
        }
        return dResult;
    }
    
    /**
     * 计算两个时间段之间包括几天
     * @param dtStartDate
     * @param dtEndDate
     * @return
     */
    public static int getDateOffset(Date dtStartDate, Date dtEndDate) {
        long quot = 0;
        dtStartDate = DateUtil.clearTime(dtStartDate);
        dtEndDate = DateUtil.clearTime(dtEndDate);
        quot = dtEndDate.getTime() - dtStartDate.getTime();
        quot = quot/1000/60/60/24;
        return (int) quot;
    }
    
    /**
     * 计算两个时间段之间包括秒差
     * @param dtStartDate
     * @param dtEndDate
     * @return
     */
    public static int getSecOffset(Date dtStartDate, Date dtEndDate) {
        long quot = 0;
        quot = dtEndDate.getTime() - dtStartDate.getTime();
        quot = quot/1000;
        return (int) quot;
    }
    
    public static int getSecOffset(String dtStartDate, String dtEndDate) {
    	Date s_date = DateUtil.formatDate(dtStartDate, "yyyy-MM-dd HH:mm:ss");
    	Date e_date = DateUtil.formatDate(dtEndDate, "yyyy-MM-dd HH:mm:ss");
    	return getSecOffset(s_date, e_date);
    }
    
    /**
     * 根据传入的时间得到当前月第一天
     * @param strDate yyyy-MM-dd格式的日期
     * @return
     */
    public static Date getMonthFirstDate(String strDate){
        Date dtCurrent = null;
        if (strDate == null) {
            dtCurrent = new Date(System.currentTimeMillis());
        } else {
            dtCurrent = strToLongDate(strDate);
        }
        return getMonthFirstDate(dtCurrent);
    }
    
    /**
     * 根据传入的时间得到当前月第一天
     * @param date yyyy-MM-dd格式的日期
     * @return
     */
    public static Date getMonthFirstDate(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int minDate = cal.getActualMinimum(Calendar.DATE);   
        cal.set(Calendar.DAY_OF_MONTH, minDate);
        return DateUtils.truncate(cal.getTime(), Calendar.DAY_OF_MONTH);
    }
    
    /**
     * 计算两个时间段之间包括几月
     * @param dtStartDate
     * @param dtEndDate
     * @return
     */
    public static int getMonthOffset(Date dtStartDate, Date dtEndDate) {
        int offset = 0;
        Calendar cal = Calendar.getInstance();
        cal.setTime(dtStartDate);
        int iStart = cal.get(Calendar.MONTH);
        int iStartYear = cal.get(Calendar.YEAR);
        cal.setTime(dtEndDate);
        int iEnd = cal.get(Calendar.MONTH);
        int iEndYear = cal.get(Calendar.YEAR);
        if (iStartYear == iEndYear) {
            offset = iEnd - iStart;
        } else {
            offset = iEnd + 12 * (iEndYear - iStartYear) - iStart;
        }
        return offset;
    }
    
    /**
     * 根据传入的时间得到当前月最后一天最后时刻
     * @param strDate yyyy-MM-dd格式的日期
     * @return
     */
    public static Date getMonthLastDate(String strDate){
        Date dtCurrent = null;
        if (strDate == null) {
            dtCurrent = new Date(System.currentTimeMillis());
        } else {
            dtCurrent = strToLongDate(strDate);
        }       
        return getMonthLastDate(dtCurrent);
    }
    
    /**
     * 根据传入的时间得到当前月最后一天最后时刻
     * @param strDate 
     * @param pattern 
     * @return
     */
    public static Date getMonthLastDate(String strDate, String pattern){
    	Date dtCurrent = formatDate(strDate, pattern);
    	return getMonthLastDate(dtCurrent);
    }
    
    /**
     * 根据传入的时间得到当前月最后一天最后时刻
     * @param strDate 
     * @return
     */
    public static Date getYearLastDate(String strDate){
    	if (StringUtils.isEmpty(strDate) || strDate.length() < 4) {
    		return null;
    	}
    	String year = strDate.substring(0, 4);
    	Date dtCurrent = formatDate(year + "1231", "yyyyMMdd");
    	return getMonthLastDate(dtCurrent);
    }
    
    /**
     * 根据传入的时间得到当前月最后一天最后时刻
     * @param date yyyy-MM-dd格式的日期
     * @return
     */
    public static Date getMonthLastDate(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int maxDate = cal.getActualMaximum(Calendar.DATE);
        cal.set(Calendar.DAY_OF_MONTH, maxDate);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }
    
    /**
     * 当前日期取周几，按中国习惯，1周一 2周二....6周六 7周日
     * @param firstDate
     * @return
     */
    public static int getWeekDay(Date firstDate) {
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(firstDate);
    	
    	int d = cal.get(Calendar.DAY_OF_WEEK) - 1;
    	if (d == 0)
    	{
    		d = 7;
    	}
    	return d;
    }
    
	public static int getDay(Date firstDate) {
		Calendar cal = Calendar.getInstance();
        cal.setTime(firstDate);
		return cal.get(Calendar.DAY_OF_MONTH);
	}
	
	public static int getMonth(Date firstDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(firstDate);
		return cal.get(Calendar.MONTH);
	}
	
	/**
	 * 返回中国习惯的年月日，例如3月是3，而不是系统的2
	 * @param date
	 * @return Integer[yyyy,MM,day]
	 */
	public static final Integer[] getYearMonthDay(Date date)
	{
		String strDate = getDate(date);
		String[] s = strDate.split("-");
		Integer[] r = new Integer[3];	
		r[0] = Integer.parseInt(s[0]);
		r[1] = Integer.parseInt(s[1]);
		r[2] = Integer.parseInt(s[2]);
		return r;
	}
	
	public static int getYear(Date firstDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(firstDate);
		return cal.get(Calendar.YEAR);
	}
	
	public static Date initDate(int year, int month, int day) {
		Calendar cal = Calendar.getInstance();
		cal.set(year, month, 1);

        int maxDate = cal.getActualMaximum(Calendar.DATE);
		if (maxDate > day) {
			cal.set(year, month, day);
		} else {
			cal.set(year, month, maxDate);
		}
		
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
		return cal.getTime();
	}
	
	/**
     * 得到相差offset天的时间
     * @param date
     * @param offset
     * @return
     */
    public static Date getDateByOffset(Date date, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_YEAR, offset);
        return cal.getTime();
    }
    
    /**
     * 得到相差offset周的日期
     * @param date
     * @param offset
     * @return
     */
    public static Date getWeekByOffset(Date date, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.WEEK_OF_YEAR, offset);
        return cal.getTime();
    }
    
    /**
     * 得到相差offset月的时间
     * @param date
     * @param offset
     * @return
     */
    public static Date getMonthByOffset(Date date, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, offset);
        return cal.getTime();
    }
	
    public final static int compareDate(Date t1, Date t2)
    {
		// String s1 = "2008-01-25 09:12:09";
		// String s2 = "2010-01-29 09:12:11";
		// java.text.DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		java.util.Calendar c1 = java.util.Calendar.getInstance();
		java.util.Calendar c2 = java.util.Calendar.getInstance();

		c1.setTime(t1);
		c2.setTime(t2);

		return c1.compareTo(c2);
		// if (result == 0)
		// System.out.println("c1相等c2");
		// else if (result < 0)
		// System.out.println("c1小于c2");
		// else
		// System.out.println("c1大于c2");
    }
    
	public static Date getFirstDateByWeek(Date date) {
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		int today = now.get(Calendar.DAY_OF_WEEK);
		int first_day_of_week = now.get(Calendar.DATE) + 2 - today; // 星期一
		if (now.get(Calendar.DAY_OF_WEEK) == 1){
			now.set(Calendar.DATE, first_day_of_week - 7);
		} else {
			now.set(Calendar.DATE, first_day_of_week);
		}
		return now.getTime();
	}
	
	public static Date getLastDateByWeek(Date date) {
		Calendar now = Calendar.getInstance();
		now.setTime(date);
		int today = now.get(Calendar.DAY_OF_WEEK);
		int first_day_of_week = now.get(Calendar.DATE) + 2 - today; // 星期一
		int last_day_of_week = first_day_of_week + 6; // 星期日
		if (now.get(Calendar.DAY_OF_WEEK) == 1){
			now.set(Calendar.DATE, last_day_of_week - 7);
		} else {
			now.set(Calendar.DATE, last_day_of_week);
		}
		return now.getTime();
	}
	
	/**
	 * 周期以周一起始，周日结束
	 * @param date
	 * @return
	 */
	public static Integer getWeekOfMonth(Date date) {
		Calendar currCal = Calendar.getInstance();
		currCal.setTime(date);
		Integer weekOfMonth = currCal.get(Calendar.WEEK_OF_MONTH);
		if (DateUtil.getWeekDay(date) == 7){
			weekOfMonth = weekOfMonth -1;
		}
		return weekOfMonth;
	}
	
	public static void main(String[] args) {
		//System.out.print(formatDate("815", "MMdd"));
		
//		String s1 = "2008-01-25 09:12:09";
//		String s2 = "2010-01-29 09:12:11";
//		java.text.DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		java.util.Calendar c1 = java.util.Calendar.getInstance();
//		java.util.Calendar c2 = java.util.Calendar.getInstance();
//		try
//		{
//			c1.setTime(df.parse(s1));
//			c2.setTime(df.parse(s2));
//		}
//		catch (java.text.ParseException e)
//		{
//			System.err.println("格式不正确");
//		}
//		int result = c1.compareTo(c2);
//		if (result == 0)
//			System.out.println("c1相等c2");
//		else if (result < 0)
//			System.out.println("c1小于c2");
//		else
//			System.out.println("c1大于c2");
		
//		System.out.println(getWeekDay(new Date()));
//		System.out.println("---------------------------------");
//		System.out.println(getWeekDay(toDate("2012-03-04")));
//		System.out.println(getWeekDay(toDate("2012-03-05")));
//		System.out.println(getWeekDay(toDate("2012-03-06")));
//		System.out.println(getWeekDay(toDate("2012-03-07")));
//		System.out.println(getWeekDay(toDate("2012-03-08")));
//		System.out.println(getWeekDay(toDate("2012-03-09")));
//		System.out.println(getWeekDay(toDate("2012-03-10")));
		System.out.println(getDate(formatDate("2012-10-13", "yyyy-MM-dd"), "yyyy年M月d日"));
	}
}
